package com.authine.cloudpivot.ext.applicationservice;

import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.ext.constants.AppConst;
import com.authine.cloudpivot.ext.constants.ConfigConstant;
import com.authine.cloudpivot.ext.constants.ModelConst;
import com.authine.cloudpivot.ext.dto.DemandGoodsDto;
import com.authine.cloudpivot.ext.dto.DemandPoolDto;
import com.authine.cloudpivot.ext.enums.demandpool.DemandGoodsStatusEnum;
import com.authine.cloudpivot.ext.enums.demandpool.DemandPoolStatusEnum;
import com.authine.cloudpivot.ext.enums.inquiry.InquiryStatusEnum;
import com.authine.cloudpivot.ext.enums.inquiry.QuotationStatusEnum;
import com.authine.cloudpivot.ext.enums.order.OrderGoodsStatusEnum;
import com.authine.cloudpivot.ext.utils.BoServiceUtils;
import com.authine.cloudpivot.ext.utils.JdbcTemplateUtils;
import com.authine.hermes.app.launcher.org.v2.UserV2;
import com.authine.hermes.app.launcher.service.ApplicationService;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.dto.bo.query.expression.Operator;
import com.authine.mvp.app.launcher.dto.bo.response.BO;
import com.authine.mvp.app.launcher.dto.bo.response.BOList;
import com.authine.mvp.app.launcher.dto.errorcode.ErrorCodeEnum;
import com.authine.mvp.app.org.dto.domainmodel.UnitType;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.util.StringUtils;

import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.authine.hermes.app.launcher.service.ApplicationServiceFoundation.CUSTOM_SERVICE;

/**
 * @ClassName DemandPoolService
 * @Description: 需求池自定义服务
 * @Author fj
 * @Date 2021/4/9
 * @Version V1.0
 **/
@Path("DemandPoolService")
@Slf4j
public class DemandPoolService extends ApplicationService {
    /**
     * 提交-更新需求池状态
     *
     * @param demandPoolDto 需求池数据
     * @return 更新结果
     */
    @Path("updateDemandPoolStatus")
    @POST
    @Operation(summary = "提交-更新需求池状态", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateDemandPoolStatus(@Parameter DemandPoolDto demandPoolDto) {
        if (demandPoolDto.getDemandPoolIdList() == null || demandPoolDto.getDemandPoolIdList().isEmpty()) {
            return SingleResponse.error("-1", "需求id不能为空");
        }
        List<Map<String, Object>> demandPoolList = new ArrayList<>();

        // 更新需求池状态
        demandPoolDto.getDemandPoolIdList().forEach(demandPoolId -> {
            Map<String, Object> demandPoolMap = Maps.newHashMap();
            demandPoolMap.put("id", demandPoolId);
            demandPoolMap.put("demand_pool_status", DemandPoolStatusEnum.DEMAND_3_APPROVE_YES.getCode());
            demandPoolList.add(demandPoolMap);
        });
        SingleResponse<BO> demandPoolUpdateBO = BoServiceUtils.updateMainBo(ModelConst.T_DEMAND_POOL, demandPoolList);
        log.info("------------------------更新需求池状态成功，返回结果：{}------------------------", JSONObject.toJSONString(demandPoolUpdateBO));

        // 根据需求池id获取需求商品信息
        SingleResponse<BOList> demandGoodsBOList = BoServiceUtils.findListByIn(ModelConst.T_DEMAND_GOODS, ConfigConstant.DEMAND_POOL_ID, demandPoolDto.getDemandPoolIdList());
        log.info("------------------------根据需求池id获取需求商品列表，查询结果：{}------------------------", JSONObject.toJSONString(demandGoodsBOList));

        demandPoolDto.setDemandGoodsIdList(Lists.newArrayList());
        demandGoodsBOList.getData().getData().forEach(demandGoodsMap -> demandPoolDto.getDemandGoodsIdList().add(demandGoodsMap.get("id").toString()));
        SingleResponse<BO> childResult = updateChildTable(demandPoolDto, DemandGoodsStatusEnum.DEMAND_GOODS_1_NEW.getCode());
        log.info("------------------------更新需求商品状态成功，返回结果：{}------------------------", JSONObject.toJSONString(childResult));
        return demandPoolUpdateBO;
    }

    /**
     * 分配-更新需求商品状态
     *
     * @param demandGoodsDto    需求商品数据
     * @return  更新结果
     */
    @Path("updateDemandGoodsStatus")
    @POST
    @Operation(summary = "分配-更新需求商品状态", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateDemandGoodsStatus(@Parameter DemandGoodsDto demandGoodsDto) {
        List<Map<String, Object>> demandGoodsList = new ArrayList<>();
        Map<String, Object> demandGoodsMap;

        // 更新需求商品状态
        for (String demandGoodsId : demandGoodsDto.getDemandGoodsIdList()) {
            demandGoodsMap = new HashMap<>();
            demandGoodsMap.put("id", demandGoodsId);
            demandGoodsMap.put("buyer", demandGoodsDto.getBuyer());
            demandGoodsMap.put("buyer_id", demandGoodsDto.getBuyerId());
            demandGoodsMap.put("demand_goods_status", DemandGoodsStatusEnum.DEMAND_GOODS_1_NEW.getCode());
            demandGoodsList.add(demandGoodsMap);
        }
        log.info("------------------------需要更新的需求商品：{}------------------------", JSONObject.toJSONString(demandGoodsList));
        SingleResponse<BO> demandGoodsUpdateBO = BoServiceUtils.updateMainBo(ModelConst.T_DEMAND_GOODS, demandGoodsList);

        List<Map<String, Object>> demandPoolList = new ArrayList<>();
        Map<String, Object> demandPool;
        // 更新需求池
        List<String> demandPoolIdList = demandGoodsDto.getDemandPoolIdList().stream().distinct().collect(Collectors.toList());
        String[] columns = new String[]{ConfigConstant.DEMAND_POOL_ID, ConfigConstant.DEMAND_GOODS_STATUS};
        Operator[] operators = new Operator[]{Operator.EQ, Operator.EQ};
        String[] columnsVal = new String[2];
        columnsVal[1] = DemandGoodsStatusEnum.DEMAND_GOODS_4_UNDISTRIBUTED.getCode();
        for (String demandPoolId : demandPoolIdList) {
            columnsVal[0] = demandPoolId;
            SingleResponse<BOList> listByComplex = BoServiceUtils.findListByComplex(ModelConst.T_DEMAND_GOODS, columns, columnsVal, operators);
            log.info("------------------------listByComplex：{}------------------------", JSONObject.toJSONString(listByComplex));
            if (listByComplex.getData().getTotal() == 0) {
                demandPool = new HashMap<>();
                demandPool.put("id", demandPoolId);
                demandPool.put("demand_pool_status", DemandPoolStatusEnum.DEMAND_3_APPROVE_YES.getCode());
                demandPoolList.add(demandPool);
            }
        }
        // 更新需求池状态
        if (demandPoolList.size() > 0) {
            SingleResponse<BO> demandPoolUpdateBO = BoServiceUtils.updateMainBo(ModelConst.T_DEMAND_POOL, demandPoolList);
            log.info("------------------------更新需求池状态成功：{}------------------------", JSONObject.toJSONString(demandPoolUpdateBO));
        }
        return demandGoodsUpdateBO;
    }

    /**
     * 需求转询价、需求商品转询价后更新状态
     *
     * @param demandPoolDto 请求数据
     * @return  更新结果
     */
    @Path("updateStatusByInquiry")
    @POST
    @Operation(summary = "需求转询价、需求商品转询价后更新状态", tags = CUSTOM_SERVICE)
    public SingleResponse<BO> updateStatusByInquiry(@Parameter DemandPoolDto demandPoolDto) {
        List<Map<String, Object>> data = new ArrayList<>();
        Map<String, Object> dataMap;
        for (String demandPoolId : demandPoolDto.getDemandPoolIdList()) {
            dataMap = new HashMap<>();
            dataMap.put("id", demandPoolId);
            dataMap.put("demand_pool_status", DemandPoolStatusEnum.DEMAND_4_INQUIRING.getCode());
            data.add(dataMap);
        }
        log.info("------------------------需求转询价需要更新的需求池列表：{}------------------------", JSONObject.toJSONString(data));
        SingleResponse<BO> demandPoolUpdateBO = BoServiceUtils.updateMainBo(ModelConst.T_DEMAND_POOL, data);

        SingleResponse<BO> childResult = updateChildTable(demandPoolDto, DemandGoodsStatusEnum.DEMAND_GOODS_2_INQUIRY.getCode());
        log.info("------------------------需求转询价后，更新需求商品成功，更新结果：{}------------------------", JSONObject.toJSONString(childResult));
        return demandPoolUpdateBO;
    }

    /**
     * 需求执行进度
     *
     * @param demandGoodsDto    请求参数
     * @return  需求执行进度列表
     */
    @Path("demandTrace")
    @POST
    @Operation(summary = "需求执行进度", tags = CUSTOM_SERVICE)
    public SingleResponse<BOList> demandTrace(@Parameter DemandGoodsDto demandGoodsDto) {
        if (StringUtils.isEmpty(demandGoodsDto.getDemandGoodsId())) {
            return SingleResponse.error("-1", "需求商品不存在");
        }
        List<Map<String, Object>> traceList = Lists.newArrayList();
        Map<String, Object> traceMap;
        BOList boList = new BOList();
        // 通过需求商品id查询询价商品
        Map<String, Object> inquiryGoodsMap = Objects.requireNonNull(JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_INQUIRY_GOODS)
                .selectField("id, partake_count, quote_count, createdTime, inquiry_id, createdBy, inquiry_goods_status"), ErrorCodeEnum.BIZ_EXCEPTION.getErrCode())
                .eq("demand_goods_id", demandGoodsDto.getDemandGoodsId())
                .queryForMap();
        log.info("------------------------通过需求商品id查询询价商品结果：{}------------------------", JSONObject.toJSONString(inquiryGoodsMap));
        if (MapUtils.isNotEmpty(inquiryGoodsMap)) {
            traceMap = Maps.newHashMap();
            BigDecimal partakeCount = inquiryGoodsMap.get("partake_count") == null ? new BigDecimal(0) : (BigDecimal) inquiryGoodsMap.get("partake_count");
            BigDecimal quoteCount = inquiryGoodsMap.get("quote_count") == null ? new BigDecimal(0) : (BigDecimal) inquiryGoodsMap.get("quote_count");
            String traceStatus = "发布询价".concat("(已参与").concat(String.valueOf(partakeCount.intValue()))
                    .concat("已报价").concat(String.valueOf(quoteCount.intValue())).concat(")");
            traceMap.put("trace_time", inquiryGoodsMap.get("createdTime"));
            traceMap.put("trace_status", traceStatus);
            traceMap.put("trace_inquiryId", inquiryGoodsMap.get("inquiry_id"));
            List<SelectorFormat> inquiryCreatedBy = getDepartmentOrUser(String.valueOf(inquiryGoodsMap.get("createdBy")), UnitType.USER.getIndex());
            traceMap.put("trace_member", inquiryCreatedBy);
            traceList.add(traceMap);
            // 增加定标记录
            if (InquiryStatusEnum.INQUIRY_GOODS_4_END.getCode().equals(inquiryGoodsMap.get("inquiry_goods_status"))) {
                // 通过询价商品id查询报价商品
                Map<String, Object> quotationGoodsMap = Objects.requireNonNull(JdbcTemplateUtils.builder(AppConst.SOURCING_CENTER, ModelConst.T_QUOTATION_GOODS)
                        .selectField("id, modifiedTime, modifiedBy"),ErrorCodeEnum.BIZ_EXCEPTION.getErrCode())
                        .eq("inquiry_goods_id", inquiryGoodsMap.get("id"))
                        .eq("quotation_goods_status", QuotationStatusEnum.QUOTATION_5_PICKETED.getCode())
                        .eq("deleted", 0)
                        .queryForMap();
                log.info("------------------------通过询价商品id查询报价商品结果：{}------------------------", JSONObject.toJSONString(quotationGoodsMap));
                if (MapUtils.isNotEmpty(quotationGoodsMap)) {
                    traceMap = Maps.newHashMap();
                    traceMap.put("trace_time", quotationGoodsMap.get("modifiedTime"));
                    traceMap.put("trace_status", "定标");
                    traceMap.put("trace_inquiryId", "");
                    List<SelectorFormat> quotationModifyBy = getDepartmentOrUser(String.valueOf(quotationGoodsMap.get("modifiedBy")), UnitType.USER.getIndex());
                    traceMap.put("trace_member", quotationModifyBy);
                    traceList.add(traceMap);
                }
                // 通过需求商品id查询订单商品关系表
                Map<String, Object> orderGoodsRelationMap = Objects.requireNonNull(JdbcTemplateUtils.builder(AppConst.ORDER_CENTER, ModelConst.T_ORDER_GOODS_RELATION)
                        .selectField("id"), ErrorCodeEnum.BIZ_EXCEPTION.getErrCode())
                        .eq("demand_goods_id", demandGoodsDto.getDemandGoodsId())
                        .queryForMap();
                log.info("------------------------通过需求商品id查询订单商品关系结果：{}------------------------", JSONObject.toJSONString(orderGoodsRelationMap));
                if (MapUtils.isNotEmpty(orderGoodsRelationMap)) {
                    // 根据订单商品关系id查询客户订单商品表
                    Map<String, Object> orderCustomerGoodsMap = Objects.requireNonNull(JdbcTemplateUtils.builder(AppConst.ORDER_CENTER, ModelConst.T_ORDER_CUSTOMER_GOODS)
                            .selectField("id, createdTime, createdBy, order_customer_goods_status, modifiedTime, modifiedBy"), ErrorCodeEnum.BIZ_EXCEPTION.getErrCode())
                            .eq("relation_id", orderGoodsRelationMap.get("id"))
                            .queryForMap();
                    log.info("------------------------通过订单商品关系查询订单商品结果：{}------------------------", JSONObject.toJSONString(orderCustomerGoodsMap));
                    if (MapUtils.isNotEmpty(orderCustomerGoodsMap)) {
                        traceMap = Maps.newHashMap();
                        traceMap.put("trace_time", orderCustomerGoodsMap.get("createdTime"));
                        traceMap.put("trace_status", "提交订单");
                        traceMap.put("trace_inquiryId", "");
                        List<SelectorFormat> orderCustomerGoodsCreatedBy = getDepartmentOrUser(String.valueOf(orderCustomerGoodsMap.get("createdBy")), UnitType.USER.getIndex());
                        traceMap.put("trace_member", orderCustomerGoodsCreatedBy);
                        traceList.add(traceMap);
                        if (OrderGoodsStatusEnum.Done.name().equals(orderCustomerGoodsMap.get("order_customer_goods_status"))) {
                            traceMap = Maps.newHashMap();
                            traceMap.put("trace_time", orderCustomerGoodsMap.get("modifiedTime"));
                            traceMap.put("trace_status", "确认收货");
                            traceMap.put("trace_inquiryId", "");
                            List<SelectorFormat> orderCustomerGoodModifyBy = getDepartmentOrUser(String.valueOf(orderCustomerGoodsMap.get("modifiedBy")), UnitType.USER.getIndex());
                            traceMap.put("trace_member", orderCustomerGoodModifyBy);
                            traceList.add(traceMap);
                        }
                    }
                }
            }
        }
        log.info("------------------------需求执行进度查询结果：{}------------------------", JSONObject.toJSONString(traceList));
        boList.setTotal(traceList.size());
        Collections.reverse(traceList);
        boList.setData(traceList);
        boList.setSchemaCode(ModelConst.T_DEMAND_TRACE);
        return SingleResponse.of(boList);
    }

    /**
     * 更新子表数据
     *
     * @param demandPoolDto 需求单数据
     * @param status        状态
     * @return  更新后结果
     */
    private SingleResponse<BO> updateChildTable(DemandPoolDto demandPoolDto, String status) {
        List<Map<String, Object>> childData = new ArrayList<>();
        Map<String, Object> childDataMap;
        String inquiry_ids = "";
        String inquiry_goods_ids = "";
        for (int i = 0; i < demandPoolDto.getDemandGoodsIdList().size(); i++) {
            childDataMap = new HashMap<>();
            if (!StringUtils.isEmpty(demandPoolDto.getInquiryId())) {
                inquiry_ids = demandPoolDto.getInquiryId();
                inquiry_goods_ids = demandPoolDto.getInquiryGoodsIdList().get(i);
            }
            childDataMap.put(ConfigConstant.INQUIRY_IDS, inquiry_ids);
            childDataMap.put(ConfigConstant.INQUIRY_GOODS_IDS, inquiry_goods_ids);
            childDataMap.put("id", demandPoolDto.getDemandGoodsIdList().get(i));
            childDataMap.put("demand_goods_status", status);
            childData.add(childDataMap);
        }
        return BoServiceUtils.updateMainBo(ModelConst.T_DEMAND_GOODS, childData);
    }

    /**
     * 根据系统字段封装成选人控件格式
     *
     * @param id    部门id
     * @param type  类型
     */
    private List<SelectorFormat> getDepartmentOrUser(String id, int type) {
        SingleResponse<UserV2> userByUserId = this.orgServiceV2.getUserByUserId(id);
        if (!userByUserId.isSuccess()) {
            throw new BizException(userByUserId.getErrMessage());
        }
        SelectorFormat userFormat = new SelectorFormat();
        userFormat.setId(userByUserId.getData().getId());
        userFormat.setType(type);
        userFormat.setName(userByUserId.getData().getName());
        return Collections.singletonList(userFormat);
    }
}
